﻿// NumberInChineseProvider.cs

// 此代码修改自 https://github.com/zmjack/Chinese/blob/master/Chinese/ChineseNumber.cs
// 本应用于 https://gitee.com/yueyinqiu5990/plum-blossom-in-winter/blob/master/src/PBIW.Operating/NumberInChineseProvider.cs

using System.Text;
using System.Text.RegularExpressions;

public sealed class NumberInChineseProvider
{
    public NumberInChineseProvider() { }

    private static readonly string[] figures = new[] { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九" };
    private static readonly string[] smallLevels = new[] { "", "十", "百", "千" };
    private static readonly string[] bigLevels = new[] { "", "万", "亿", "兆", "京", "垓", "秭", "穰" };

    private static IEnumerable<(int index, T value)> WithIndex<T>(
        IEnumerable<T> enumerable, int starting)
    {
        foreach (var item in enumerable)
        {
            yield return (starting, item);
            starting++;
        }
    }

    private string GetStringOfOneLevel(string singles, int bigLevelIndex)
    {
        if (singles.Length == 0)
            return string.Empty;

        var sb = new StringBuilder();
        var frontIsZero = false;

        foreach (var (index, single) in WithIndex(singles, 1))
        {
            if (single is '0')
                frontIsZero = true;
            else
            {
                var value = figures[single - '0'];
                var singleNumberUnit = smallLevels[singles.Length - index];

                if (frontIsZero)
                    _ = sb.Append($"{figures[0]}{value}{singleNumberUnit}");
                else
                    _ = sb.Append($"{value}{singleNumberUnit}");

                frontIsZero = false;
            }
        }

        if (sb.Length is 0)
            return figures[0];
        else
            return sb.Append(bigLevels[bigLevelIndex]).ToString();
    }

    private IEnumerable<(string str, int level)> CutLevelFromEnd(string str)
    {
        int level = 0;
        for (bool notEnded = true; notEnded; level++)
        {
            int ending = str.Length - level * 4;
            int starting = ending - 4;
            if (starting <= 0)
            {
                notEnded = false;
                starting = 0;
            }
            yield return (str[starting..ending], level);
        }
    }

    public string GetString(int value)
    {
        var stringValue = Math.Abs(value).ToString();

        var resultEnumrable = this.CutLevelFromEnd(stringValue)
            .Reverse().Select((s) => this.GetStringOfOneLevel(s.str, s.level));
        var resultString = string.Join("", resultEnumrable);

        resultString = Regex.Replace(resultString, $"{figures[0]}{{2,}}", figures[0]);
        if (resultString.StartsWith("一十"))
            resultString = resultString[1..];
        if (value < 0)
            resultString = $"负{resultString}";
        return resultString;
    }
}